Traditionally client-server applications have been tested in one of the following ways. First, a test tool exercises a client and validates that the client responds properly to user inputs. The behavior of the server is indirectly tested by validating the correct behavior of the client, since the server output affects what the client displays to the user. In this scenario both the behavior of the client application and the server application are being tested. An example is a test tool that is used to automate testing of a Java client or of a web browser.
Second, instead of testing a client application directly, a test tool can emulate a client by directly interacting with the server and acting like a client. However, in these cases, a client application is not being tested. Instead, the behavior of the server is tested by the test tool sending different requests or sequences of requests to the server and then validating the contents of the responses returned by the server.
Another way that client-server applications are tested is by using unit tests that run against the server-side code. In this case, the tests are not run in the server's runtime environment rather, they are simply unit tests that run against the application code. They typically require that many method calls be stubbed out, since the test cases are not run against a running web application, but only against the source code of the application.
An adaptation of this method is to use unit tests that run in-container. In-container tests require that the server application be running as the tests are run. Typically they involve executing the test case to make special requests to the server and adding in or turning on an additional server framework that intercepts the special server requests. The special requests may include parameters that are only intended to be used by the additional server framework. However, since the tests are performed using the additional framework and not using typical client requests, the behavior of the server is not tested in the actual production environment in which it needs to be run. Additionally, the framework requires the setup work of installing and configuring it.
The first two methods of testing are performed from the client side of the application, without directly validating the server as it runs. The server is tested by observing its output, either within a client or within the output itself. The third method (along with its adaptation) is performed from “inside” the server, without doing any validation on the output it produces for the client. Using the first three methods, if a user desires to test both client-side and server-side behavior, he needs to run different tests at different times in order to accomplish this.
The separation of client and server-based tests is undesirable in many cases. Server applications are meant to be accessed through a remote client. Therefore, it is understandably difficult to create tests that run against the server in the server's runtime environment without using a client to send requests to the server. It can be difficult or even impossible to replicate the server state, thus making validation just as difficult. On the other hand, simply validating server output from the client perspective is not a sufficient method of testing either, as there may be problems in the server application that do not make themselves visible in the output.
Therefore, there is a need for a new system and method to define a test case that exercises the server from the client perspective, without modifying the server's environment, and at the same time is able to validate server-side state to validate whether the server is operating properly.